#include <iostream>
#include <fstream>
#include <cmath>
#include <algorithm>
#include <vector>
#include "Spline.h"
#include <jsoncpp/json/json.h>
using namespace std;

class Function2 : public Function
{
public:
    double operator()(double _x)
    {
        double f;
        f = 1 / (1 + _x * _x);
        return f;
    }
    double diff1(double _x) 
    {
        double f;
        f = -2.0 * _x / pow(1.0 + _x * _x, 2);
        return f;  
    }
    double diff2(double _x)
    {
        double f;
        f = 2.0 * (3.0 * _x * _x - 1.0) / pow(1.0 + _x * _x, 3);
        return f;  
    }
};

int main()
{
    Json::Reader reader;
    Json::Value root;
    ifstream in("questionCD.json", ios::binary);
    vector<double> num1, num2, output;
    Function2 f;
    if (reader.parse(in, root))
	{
        for (int i = 0; i < root["num1"].size(); i++)
	    {
            double num = root["num1"][i].asDouble();
            num1.push_back(num);
	    }
        for (int i = 0; i < root["num2"].size(); i++)
	    {
            double num = root["num2"][i].asDouble();
            num2.push_back(num);
	    }
        for (int i = 0; i < root["output"].size(); i++)
	    {
            double num = root["output"][i].asDouble();
            output.push_back(num);
        }
    }
    BsplineInterpolation B1(f, num1, 1, 3);
    B1.solve();
    for (int i = 0; i < 1000; i++)
	{
        cout << B1(num1[0] + i * 0.01) << ",";
    }
    cout << B1(num1[num1.size() - 1]) << endl;

    for (int i = 0; i < 1000; i++)
	{
        cout << fabs(B1(num1[0] + i * 0.01) - f(num1[0] + i * 0.01)) << ",";
    }
    cout << fabs(B1(num1[num1.size() - 1]) - f(num1[num1.size() - 1])) << endl;
    
    BsplineInterpolation B2(f, num2, 1, 1);
    B2.solve();
    for (int i = 0; i < 900; i++)
	{
        cout << B2(num2[0] + i * 0.01) << ",";
    }
    cout << B2(num2[num2.size() - 1]) << endl;

    for (int i = 0; i < 900; i++)
	{
        cout << fabs(B2(num2[0] + i * 0.01) - f(num2[0] + i * 0.01)) << ",";
    }
    cout << fabs(B2(num2[num2.size() - 1]) - f(num2[num2.size() - 1])) << endl;

    cout << "三次样条误差:" << endl;
    for (int i = 0; i < output.size() - 1; i++)
	{
        cout << fabs(B1(output[i]) - f(output[i])) << ",";
    }
    cout << fabs(B1(output[output.size() - 1]) - f(output[output.size() - 1])) << endl;
    cout << "线性样条误差:" << endl;
    for (int i = 0; i < output.size() - 1; i++)
    {
        cout << fabs(B2(output[i]) - f(output[i])) << ",";
    }
    cout << fabs(B2(output[output.size() - 1]) - f(output[output.size() - 1])) << endl;

    return 0;
}
